//
// Created by 32827 on 2024/5/19.
//
#include "yzl_lcd1306.h"
#ifdef YZL_I2C_1306_ENABLE
#include "yzl_i2c_lcd1306.h"

uint8_t sram_1306[YZ_SCREEN_HEIGHT*YZ_SCREEN_WIDTH*sizeof(YZ_COLOR)/8]={0};
#if YZL_I2C_SoftPort_ENABLE

//TODO

#else
#include "yz_time.h"

YZF_RESULT yzl_1306_screen_init(YZF_I2C_POINTER i2c){
    yzl_1306_open(i2c);
    yz_time_delay_ms(1);
    yzl_1306_light_screen(i2c);
    yz_time_delay_ms(1);
    yzl_1306_light_level_screen(i2c,128);
    yz_time_delay_ms(1);
    yzl_1306_ram_inc_set(i2c,YZL_1306_RAM_INC_MODE_PAGE);
    yz_time_delay_ms(1);
    yzl_1306_direction_set(i2c,YZL_1306_DIRECTION_LEFT_TO_RIGHT);
    yz_time_delay_ms(1);
    yzl_1306_direction_set(i2c,YZL_1306_DIRECTION_BOTTOM_TO_TOP);
    yz_time_delay_ms(1);
    yzl_1306_content_screen(i2c);
    yz_time_delay_ms(1);
    yzl_1306_clock_set(i2c,YZL_1306_LED_CLOCK_MAX);
    return YZF_OK;
}
YZF_RESULT yzl_1306_clear(uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight, YZ_COLOR usColor){
    yzl_1306_draw_rect(usX,usY,usWidth,usHeight,YZF_TRUE,usColor);
    return YZF_OK;
}
#include "yz_log.h"
YZF_RESULT yzl_1306_draw_rect(uint16_t usX_Start, uint16_t usY_Start, uint16_t usWidth, uint16_t usHeight, uint8_t ucFilled, YZ_COLOR usColor){
    //for 1306
    uint16_t line= YZ_SCREEN_HEIGHT/8;
    uint16_t column=YZ_SCREEN_WIDTH;
    if(ucFilled){
        //eline 结束行
        //sline 开始行
        uint16_t eline = (usY_Start + usHeight) / 8 + ((usY_Start + usHeight) % 8 ? 1 : 0);
        uint16_t sline = usY_Start / 8;
        for(int y=sline;y<(eline>=8?8:eline);y++) {
            if (y > sline && y < eline - 1) {
                for (int x = 0; x < usWidth; x++) {
                    if((y * column + usX_Start + x)>=1024){
                        yz_error("[0]out of 1024\n");
                    }
                    sram_1306[y * column + usX_Start + x] = usColor.v;
                }
            } else if (y == sline && (y+1) == eline) {
                uint8_t sy = y ? usY_Start % 7 : 0;//start y
                uint8_t ey = ((y + 1) == eline) ? (usY_Start + usHeight) % 8 : 7;// end y
                uint8_t mask = (0xFF << sy) & (0xFF >> (7 - ey));
                for (int x = 0; x < usWidth; x++) {
                    if((y * column + usX_Start + x)>=1024){
                        yz_error("[1]out of 1024\n");
                    }
                    sram_1306[y * column + usX_Start + x] = (sram_1306[y * column + usX_Start + x] & ~mask) | (usColor.v & mask);
                }
            } else if(y == sline){
                uint8_t mask = (0xFF << (usY_Start % 7));
                for (int x = 0; x < usWidth; x++) {
                    if((y * column + usX_Start + x)>=1024){
                        yz_error("[2]out of 1024\n");
                    }
                    sram_1306[y * column + usX_Start + x] = (sram_1306[y * column + usX_Start + x] & ~mask) | (usColor.v & mask);
                }
            } else {
                uint8_t mask = (0xFF >> (7 - ((usY_Start + usHeight) % 8)));
                for (int x = 0; x < usWidth; x++) {
                    if((y * column + usX_Start + x)>=1024){
                        yz_error("[3]out of 1024\n");
                    }
                    sram_1306[y * column + usX_Start + x] = (sram_1306[y * column + usX_Start + x] & ~mask) | (usColor.v & mask);
                }
            }
        }
    }else{
        yzl_1306_draw_line(usX_Start, usY_Start, usX_Start + usWidth - 1, usY_Start, usColor);
        yzl_1306_draw_line(usX_Start, usY_Start + usHeight - 1, usX_Start + usWidth - 1, usY_Start + usHeight - 1,
                              usColor);
        yzl_1306_draw_line(usX_Start, usY_Start, usX_Start, usY_Start + usHeight - 1, usColor);
        yzl_1306_draw_line(usX_Start + usWidth - 1, usY_Start, usX_Start + usWidth - 1, usY_Start + usHeight - 1,
                              usColor);
    }
    return YZF_OK;
}
YZF_RESULT yzl_1306_refresh(YZF_I2C_POINTER i2c){
    for (int i = 0; i < YZ_SCREEN_HEIGHT/8; i++) {
        yzl_1306_page_set(i2c,i);
        yz_time_delay_ms(1);
        yzl_1306_col_low_set(i2c,2);
        yz_time_delay_ms(1);
        yzl_1306_col_high_set(i2c,0);
        yz_time_delay_ms(1);
        yzl_1306_datas_write(i2c, &sram_1306[i*YZ_SCREEN_WIDTH],128);
        yz_time_delay_ms(1);
    }
    return YZF_OK;
}
YZF_RESULT yzl_1306_draw_pixel(uint16_t usX, uint16_t usY, YZ_COLOR usColor){
    if(usX>=YZ_SCREEN_WIDTH||usY>=YZ_SCREEN_HEIGHT)return YZF_ERROR;
    uint16_t line= usY/8;
    uint8_t mask=0x1<<(usY%8);
    sram_1306[line*YZ_SCREEN_WIDTH+usX]=(sram_1306[line*YZ_SCREEN_WIDTH+usX]&~mask)|(usColor.v&mask);
    return YZF_OK;
}
YZ_COLOR yzl_1306_read_pixel(uint16_t usX, uint16_t usY){
    if(usX>=YZ_SCREEN_WIDTH||usY>=YZ_SCREEN_HEIGHT)return WHITE;
    uint16_t line= usY/8;
    uint8_t mask=0x1<<(usY%8);
    return (sram_1306[line*YZ_SCREEN_WIDTH+usX]&mask)?WHITE:BLACK;
}
YZF_RESULT yzl_1306_draw_circle(uint16_t usX_Center, uint16_t usY_Center, uint16_t usRadius, uint8_t ucFilled,YZ_COLOR usColor){
    int16_t sCurrentX, sCurrentY;
    int16_t sError;


    sCurrentX = 0; sCurrentY = usRadius;

    sError = 3 - ( usRadius << 1 );     //判断下个点位置的标志


    while ( sCurrentX <= sCurrentY )
    {
        int16_t sCountY;


        if ( ucFilled )
            for ( sCountY = sCurrentX; sCountY <= sCurrentY; sCountY ++ )
            {
                yzl_1306_draw_pixel(usX_Center + sCurrentX, usY_Center + sCountY, usColor);           //1，研究对象
                yzl_1306_draw_pixel(usX_Center - sCurrentX, usY_Center + sCountY, usColor);           //2
                yzl_1306_draw_pixel(usX_Center - sCountY, usY_Center + sCurrentX, usColor);           //3
                yzl_1306_draw_pixel(usX_Center - sCountY, usY_Center - sCurrentX, usColor);           //4
                yzl_1306_draw_pixel(usX_Center - sCurrentX, usY_Center - sCountY, usColor);           //5
                yzl_1306_draw_pixel(usX_Center + sCurrentX, usY_Center - sCountY, usColor);           //6
                yzl_1306_draw_pixel(usX_Center + sCountY, usY_Center - sCurrentX, usColor);           //7
                yzl_1306_draw_pixel(usX_Center + sCountY, usY_Center + sCurrentX, usColor);           //0
            }

        else
        {
            yzl_1306_draw_pixel(usX_Center + sCurrentX, usY_Center + sCurrentY, usColor);             //1，研究对象
            yzl_1306_draw_pixel(usX_Center - sCurrentX, usY_Center + sCurrentY, usColor);             //2
            yzl_1306_draw_pixel(usX_Center - sCurrentY, usY_Center + sCurrentX, usColor);             //3
            yzl_1306_draw_pixel(usX_Center - sCurrentY, usY_Center - sCurrentX, usColor);             //4
            yzl_1306_draw_pixel(usX_Center - sCurrentX, usY_Center - sCurrentY, usColor);             //5
            yzl_1306_draw_pixel(usX_Center + sCurrentX, usY_Center - sCurrentY, usColor);             //6
            yzl_1306_draw_pixel(usX_Center + sCurrentY, usY_Center - sCurrentX, usColor);             //7
            yzl_1306_draw_pixel(usX_Center + sCurrentY, usY_Center + sCurrentX, usColor);             //0
        }


        sCurrentX ++;


        if ( sError < 0 )
            sError += 4 * sCurrentX + 6;

        else
        {
            sError += 10 + 4 * ( sCurrentX - sCurrentY );
            sCurrentY --;
        }
    }
    return YZF_OK;
}
YZF_RESULT yzl_1306_draw_line (uint16_t usX1, uint16_t usY1, uint16_t usX2, uint16_t usY2, YZ_COLOR usColor )
{
    uint16_t us;
    uint16_t usX_Current, usY_Current;

    int32_t lError_X = 0, lError_Y = 0, lDelta_X, lDelta_Y, lDistance;
    int32_t lIncrease_X, lIncrease_Y;


    lDelta_X = usX2 - usX1; //计算坐标增量
    lDelta_Y = usY2 - usY1;

    usX_Current = usX1;
    usY_Current = usY1;


    if ( lDelta_X > 0 )
        lIncrease_X = 1; //设置单步方向

    else if ( lDelta_X == 0 )
        lIncrease_X = 0;//垂直线

    else
    {
        lIncrease_X = -1;
        lDelta_X = - lDelta_X;
    }


    if ( lDelta_Y > 0 )
        lIncrease_Y = 1;

    else if ( lDelta_Y == 0 )
        lIncrease_Y = 0;//水平线

    else
    {
        lIncrease_Y = -1;
        lDelta_Y = - lDelta_Y;
    }


    if (  lDelta_X > lDelta_Y )
        lDistance = lDelta_X; //选取基本增量坐标轴

    else
        lDistance = lDelta_Y;


    for ( us = 0; us <= lDistance + 1; us ++ )//画线输出
    {
        yzl_1306_draw_pixel(usX_Current, usY_Current, usColor);//画点

        lError_X += lDelta_X ;
        lError_Y += lDelta_Y ;

        if ( lError_X > lDistance )
        {
            lError_X -= lDistance;
            usX_Current += lIncrease_X;
        }

        if ( lError_Y > lDistance )
        {
            lError_Y -= lDistance;
            usY_Current += lIncrease_Y;
        }

    }

    return YZF_OK;
}
#endif
#endif